package com.yic.module.device.service.receive;

import cn.hutool.core.util.ObjectUtil;
import com.yic.framework.security.core.util.SecurityFrameworkUtils;
import com.yic.module.device.controller.admin.device.vo.DeviceUpdateReqVO;
import com.yic.module.device.dal.dataobject.device.DeviceDO;
import com.yic.module.device.dal.dataobject.fault.FaultDO;
import com.yic.module.device.service.device.DeviceService;
import com.yic.module.device.service.resume.ResumeService;
import com.yic.module.system.api.user.AdminUserApi;
import com.yic.module.system.api.user.dto.AdminUserRespDTO;
import com.yic.module.system.enums.common.ApproveEnum;
import com.yic.module.system.enums.dict.DeviceResumeTypeEnum;
import com.yic.module.system.enums.dict.DeviceUseStatusEnum;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;

import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;

import java.time.LocalDateTime;
import java.util.*;
import com.yic.module.device.controller.admin.receive.vo.*;
import com.yic.module.device.dal.dataobject.receive.ReceiveDO;
import com.yic.framework.common.pojo.PageResult;

import com.yic.module.device.convert.receive.ReceiveConvert;
import com.yic.module.device.dal.mysql.receive.ReceiveMapper;

import static com.yic.framework.common.exception.util.ServiceExceptionUtil.exception;
import static com.yic.module.device.enums.ErrorCodeConstants.*;

/**
 * 领用申请 Service 实现类
 *
 * @author 系统管理员
 */
@Service
@Validated
public class ReceiveServiceImpl implements ReceiveService {

    @Resource
    private ReceiveMapper receiveMapper;
    @Resource
    private DeviceService deviceService;
    @Resource
    private ResumeService resumeService;
    @Resource
    private AdminUserApi adminUserApi;

    @Override
    public Long createReceive(ReceiveCreateReqVO createReqVO) {
        validateCreateOrUpdate(null, createReqVO.getCode());
        checkDevice(createReqVO.getDeviceId());
        // 插入
        ReceiveDO receive = ReceiveConvert.INSTANCE.convert(createReqVO);
        AdminUserRespDTO user = adminUserApi.getUser(SecurityFrameworkUtils.getLoginUserId());
        receive.setUserId(user.getId());
        receive.setDeptId(user.getDeptId());
        receiveMapper.insert(receive);
        // 返回
        return receive.getId();
    }

    /**
     * 校验设备是否被领用
     * @param deviceId
     */
    private void checkDevice(Long deviceId){
        DeviceDO device = deviceService.get(deviceId);
        // 校验当前设备是否被领用
        if (DeviceUseStatusEnum.USEING.getDeviceUseStatus().equals(device.getUseStatus())) {
            throw exception(REFUND_NOT_ALLOW);
        }

    }

    @Override
    public void updateReceive(ReceiveUpdateReqVO updateReqVO) {
        // 校验存在
        ReceiveDO receive = validateCreateOrUpdate(updateReqVO.getId(), updateReqVO.getCode());
        if (!ApproveEnum.WAIT.getApprove().equals(receive.getApprove())){
            throw exception(RECEIVED_NOT_CHANGE);
        }
        checkDevice(updateReqVO.getDeviceId());
        // 更新
        ReceiveDO updateObj = ReceiveConvert.INSTANCE.convert(updateReqVO);
        receiveMapper.updateById(updateObj);
    }

    @Override
    public void deleteReceive(Long id) {
        // 校验存在
        ReceiveDO receive = validateReceiveExists(id);
        if (!ApproveEnum.WAIT.getApprove().equals(receive.getApprove())){
            throw exception(RECEIVED_NOT_CHANGE);
        }
        // 删除
        receiveMapper.deleteById(id);
    }

    private ReceiveDO validateCreateOrUpdate(Long id, String code){
        return validateCodeExist(id, code);
    }

    private ReceiveDO validateCodeExist(Long id, String code){
        ReceiveDO receiveDO = receiveMapper.selectByCode(code);
        if (ObjectUtil.isEmpty(receiveDO)){
            return receiveDO;
        }
        if (id == null){
            throw exception(RECEIVE_CODE_EXISTS);
        }
        if (!id.equals(receiveDO.getId())){
            throw exception(RECEIVE_CODE_EXISTS);
        }
        return receiveDO;
    }

    private ReceiveDO validateReceiveExists(Long id) {
        ReceiveDO receiveDO = receiveMapper.selectById(id);
        if (receiveDO == null) {
            throw exception(RECEIVE_NOT_EXISTS);
        }
        return receiveDO;
    }

    @Override
    public ReceiveDO getReceive(Long id) {
        return receiveMapper.selectById(id);
    }

    @Override
    public List<ReceiveDO> getReceiveList(Collection<Long> ids) {
        return receiveMapper.selectBatchIds(ids);
    }

    @Override
    public PageResult<ReceiveDO> getReceivePage(ReceivePageReqVO pageReqVO) {
        return receiveMapper.selectPage(pageReqVO);
    }

    @Override
    public List<ReceiveDO> getReceiveList(ReceiveExportReqVO exportReqVO) {
        return receiveMapper.selectList(exportReqVO);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void approveReceive(Long id) {
        ReceiveDO receive = validateReceiveExists(id);
        if (!ApproveEnum.WAIT.getApprove().equals(receive.getApprove())) {
            throw exception(RECEIVED_NOT_CHANGE);
        }
        receive.setApprove(ApproveEnum.PASS.getApprove());
        receive.setApproveTime(LocalDateTime.now());
        receiveMapper.updateById(receive);
        AdminUserRespDTO user = adminUserApi.getUser(receive.getUserId());
        // 更新设备台账信息
        deviceService.updateReceiveInfo(receive.getDeviceId(), receive.getUserId(), receive.getLoacation(), user.getDeptId(), receive.getFactoryId(), receive.getCenterId(), DeviceUseStatusEnum.USEING.getDeviceUseStatus());
        // 登记设备履历表
        resumeService.createResume(receive.getDeviceId(), DeviceResumeTypeEnum.RECEIVE.getDeviceResumeType(), "设备领用", receive.getId(), receive.getUserId(), receive.getCreateTime());
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void cancelReceive(Long id) {
        ReceiveDO receive = validateReceiveExists(id);
        if (!ApproveEnum.PASS.getApprove().equals(receive.getApprove())) {
            throw exception(RECEIVED_NOT_CHANGE);
        }
        receive.setApprove(ApproveEnum.WAIT.getApprove());
        receiveMapper.updateById(receive);
        // 更新设备台账信息
        deviceService.updateReceiveInfo(receive.getDeviceId(), receive.getUserId(), receive.getLoacation(), null, receive.getFactoryId(), receive.getCenterId(), DeviceUseStatusEnum.STOP.getDeviceUseStatus());
        // 删除设备履历表
        resumeService.deleteResumeBySourceId(id, DeviceResumeTypeEnum.RECEIVE.getDeviceResumeType());
    }

}
